home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
001-025
/
disk_005
/
timer
/
timer.c
< prev
Wrap
C/C++ Source or Header
|
1992-05-06
|
11KB
|
408 lines
/*
*
* DISCLAIMER:
*
* This program is provided as a service to the programmer
* community to demonstrate one or more features of the Amiga
* personal computer. These code samples may be freely used
* for commercial or noncommercial purposes.
*
* Commodore Electronics, Ltd ("Commodore") makes no
* warranties, either expressed or implied, with respect
* to the program described herein, its quality, performance,
* merchantability, or fitness for any particular purpose.
* This program is provided "as is" and the entire risk
* as to its quality and performance is with the user.
* Should the program prove defective following its
* purchase, the user (and not the creator of the program,
* Commodore, their distributors or their retailers)
* assumes the entire cost of all necessary damages. In
* no event will Commodore be liable for direct, indirect,
* incidental or consequential damages resulting from any
* defect in the program even if it has been advised of the
* possibility of such damages. Some laws do not allow
* the exclusion or limitation of implied warranties or
* liabilities for incidental or consequential damages,
* so the above limitation or exclusion may not apply.
*
*/
/* SIMPLE TIMER EXAMPLE PROGRAM:
*
* Includes dynamic allocation of data structures needed to communicate
* with the timer device as well as the actual device IO
*
* Author: Rob Peck, 12/1/85 */
#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/memory.h"
#include "exec/interrupts.h"
#include "exec/ports.h"
#include "exec/libraries.h"
#include "exec/io.h"
#include "exec/tasks.h"
#include "exec/execbase.h"
#include "exec/devices.h"
#include "devices/timer.h"
long TimerBase; /* to get at the time comparison functions */
main()
{
LONG error;
LONG days, minutes,seconds;
struct timeval mytimeval;
struct timeval oldtimeval; /* save what system thinks is
* the time.... we'll advance it
* temporarily
*/
printf("\ntimer test");
TimeDelay(2,0,0);
printf("\nAfter 2 seconds delay");
TimeDelay(4,0,0);
printf("\nAfter 4 seconds delay");
TimeDelay(0,500000,0); /* 500,000 seconds = 1/2 second */
printf("\nAfter 1/2 second delay");
printf("\n\n");
error = Execute("date",0,0); /* normal system startup file
* opens dos.library, so it is
* ok in such cases to use dos calls */
GetSysTime(&oldtimeval);
printf("\nCurrent system time is %ld current seconds",
oldtimeval.tv_secs);
printf("\nSetting a new system time");
days = 1000 + oldtimeval.tv_secs / (24*60*60);
minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
SetNewTime(days, minutes, seconds);
/* (if user executes the AmigaDOS DATE command now, he will
* see that the time has advanced something over 1000 days */
printf("\n\n");
error = Execute("date",0,0); /* normal system startup file
* opens dos.library, so it is
* ok in such cases to use dos calls */
GetSysTime(&mytimeval);
printf("\nCurrent system time is %ld.%06ld",
mytimeval.tv_secs,mytimeval.tv_micro);
GetSysTime(&mytimeval);
printf("\nCurrent system time is %ld.%06ld",
mytimeval.tv_secs,mytimeval.tv_micro);
GetSysTime(&mytimeval);
printf("\nCurrent system time is %ld.%06ld",
mytimeval.tv_secs,mytimeval.tv_micro);
/* added the microseconds part to show that time keeps
* increasing even though you ask many times in a row */
printf("\nResetting to former time");
days = oldtimeval.tv_secs / (24*60*60);
minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
SetNewTime(days, minutes, seconds);
GetSysTime(&mytimeval);
printf("\nCurrent system time is %ld.%06ld",
mytimeval.tv_secs,mytimeval.tv_micro);
TimerBase = GetTimerBase();
/* just shows how to set up for using
* the timer functions, does not demonstrate
* the functions themselves. (TimerBase must
* have a legal value before AddTime, SubTime or CmpTime
* are performed.
*/
}
/* *********************************************************************** */
/* Timer function - timedelay(seconds,microseconds)
Your task is put to sleep for the specified time interval.
If seconds > 0, then UNIT_VBLANK is used, delay is in multiples of
60ths of a second. If seconds < 0, then UNIT_MICROHZ is used for
more precision.
Returns value of 0 if no errors, nonzero (and no task sleeping)
Notice that since this is a multi-tasking system, the delays
shown here must be considered to be only approximate.
Also note that this function is used primarily to show how
a timer device is accessed, including the creation of the
message port and a message structure (IOStdReq). Note that
there is a Delay(interval) function already in the DOS.library.
(See the DOS developer's manual for details).
*/
/* *********************************************************************** */
extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();
struct timerequest
*PrepareTimer(precision)
SHORT precision;
{
/* return a pointer to a time request. If any problem, return NULL */
int error;
SHORT whichunit;
struct MsgPort *timerport;
struct timerequest *timermsg;
timerport = CreatePort(0,0);
if (timerport == NULL)
return(NULL); /* Error during CreatePort */
timermsg = (struct timerequest *)CreateExtIO(
timerport,sizeof(struct timerequest));
if (timermsg == NULL)
{
DeletePort(timerport);
return(NULL); /* Error during CreateExtIO */
}
if(precision) /* if true, use precision timer ( under 1 second ) */
whichunit = UNIT_MICROHZ;
else
whichunit = UNIT_VBLANK;
error = OpenDevice(TIMERNAME, whichunit, timermsg, 0);
if (error != 0)
{
DeleteExtIO(timermsg,sizeof(struct timerequest));
DeletePort(timerport);
return(NULL); /* Error during OpenDevice */
}
return(timermsg);
}
int
GetTimerBase()
{
int tbase;
struct timerequest *tr;
tr = PrepareTimer();
tbase = (int)tr->tr_node.io_Device;
DeleteTimer(tr);
return(tbase);
}
int
TimeDelay(seconds,microseconds,precision)
/* more precise timer than AmigaDOS Delay() */
ULONG seconds,microseconds;
int precision;
{
int precise;
struct timerequest *tr;
if(seconds < 0 || precision != 0)
/* do delay in terms of microseconds */
precise = TRUE; /* yes, use the precision timer. */
else
precise = FALSE; /* no, not necessary */
tr = PrepareTimer(precise);
/* get a pointer to an initialized
* timer request block */
if(tr == NULL) return(-1); /* any nonzero return says timedelay
* routine didn't work. */
WaitForTimer(tr,seconds,microseconds);
DeleteTimer(tr); /* deallocate temporary structures */
return(0);
} /* end of timedelay */
int
WaitForTimer(tr,seconds,microseconds)
ULONG seconds,microseconds;
struct timerequest *tr;
{
tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */
tr->tr_time.tv_secs = seconds; /* seconds */
tr->tr_time.tv_micro = microseconds; /* microseconds */
DoIO( tr ); /* post request to the timer */
/* goes to sleep till done */
return(0);
}
int
SetNewTime(day,min,sec)
LONG day, min,sec; /* days since 1 Jan 78 plus minutes */
{
struct timerequest *tr;
tr = PrepareTimer(TRUE); /* MUST use Precise timer for this */
if(tr == 0) return(-1); /* non zero return says error */
tr->tr_node.io_Command = TR_SETSYSTIME;
tr->tr_time.tv_secs = (24 * 60 * 60 * day) + (60 * min) + sec;
tr->tr_time.tv_micro = 0;
DoIO( tr );
DeleteTimer(tr);
return(0);
}
int
GetSysTime(tv)
struct timeval *tv;
{
struct timerequest *tr;
tr = PrepareTimer(TRUE); /* MUST use Precise timer for this */
if(tr == 0) return(-1); /* non zero return says error */
tr->tr_node.io_Command = TR_GETSYSTIME;
DoIO( tr );
tv->tv_secs = tr->tr_time.tv_secs;
tv->tv_micro = tr->tr_time.tv_micro;
DeleteTimer(tr);
return(0);
}
int
DeleteTimer(tr)
struct timerequest *tr;
{
struct MsgPort *tp;
tp = tr->tr_node.io_Message.mn_ReplyPort;
if(tr != 0)
{
CloseDevice(tr);
DeleteExtIO(tr,sizeof(struct timerequest));
}
if(tp != 0)
DeletePort(tp);
return(0);
}
/***********************************************************************
*
* Exec Support Function -- Extended IO Request
*
***********************************************************************/
extern APTR AllocMem();
/****** exec_support/CreateExtIO **************************************
*
* NAME
* CreateExtIO() -- create an Extended IO request
*
* SYNOPSIS
* ioReq = CreateExtIO(ioReplyPort,size);
*
* FUNCTION
* Allocates memory for and initializes a new IO request block
* of a user-specified number of bytes.
*
* INPUTS
* ioReplyPort - a pointer to an already initialized
* message port to be used for this IO request's reply port.
*
* RESULT
* Returns a pointer to the new block. Pointer is of the type
* struct IORequest.
*
* 0 indicates inability to allocate enough memory for the request block
* or not enough signals available.
*
* EXAMPLE
* struct IORequest *myBlock;
* if( (myBlock = CreateExtIO(myPort,sizeof(struct IOExtTD)) == NULL)
* exit(NO_MEM_OR_SIGNALS);
*
* example used to allocate space for IOExtTD (trackdisk driver
* IO Request block for extended IO operations).
*
* SEE ALSO
* DeleteExtIO
*
***********************************************************************/
struct IORequest *CreateExtIO(ioReplyPort,size)
struct MsgPort *ioReplyPort;
LONG size;
{
struct IORequest *ioReq;
if (ioReplyPort == 0)
return ((struct IORequest *) 0);
ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);
if (ioReq == 0)
return ((struct IORequest *) 0);
ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
ioReq -> io_Message.mn_Node.ln_Pri = 0;
ioReq -> io_Message.mn_ReplyPort = ioReplyPort;
return (ioReq);
}
/****** exec_support/DeleteExtIO **************************************
*
* NAME
* DeleteExtIO() - return memory allocated for extended IO request
*
* SYNOPSIS
* DeleteExtIO(ioReq,size);
*
* FUNCTION
* See summary line at NAME. Also frees the signal bit which
* had been allocated by the call to CreateExtIO.
*
* INPUTS
* A pointer to the IORequest block whose resources are to be freed.
*
* RESULT
* Frees the memory. Returns (no error conditions shown)
*
* EXAMPLE
* struct IORequest *myBlock;
* DeleteExtIO(myBlock,(sizeof(struct IOExtTD)));
*
* example shows that CreateExtIO had been used to create a trackdisk
* (extended) IO Request block.
*
* SEE ALSO
* CreateExtIO
*
**************************************************************************/
DeleteExtIO(ioExt,size)
struct IORequest *ioExt;
LONG size;
{
ioExt -> io_Message.mn_Node.ln_Type = 0xff;
ioExt -> io_Device = (struct Device *) -1;
ioExt -> io_Unit = (struct Unit *) -1;
FreeMem (ioExt, size);
}